package model.handler.fileHandling;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.CopyOption;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import enums.Property;
import model.Configuration;
import model.handler.databaseHandling.QueryFactory;
import model.invoicing.DateHandler;

/**
 * Utility class handles all interaction with files.
 * @author Matthias Haupt
 *
 */
public final class FileHandler {

	private FileHandler(){ throw new AssertionError("Utility class musn't be invoked.");}
	
	private final static Logger log = LogManager.getLogger("ERROR");
	private final static Logger debug = LogManager.getLogger("DEBUG");
	
	/**
	 * Saves the database file to a given path leading to an usb device.
	 */
	public static void saveDatabase(){
		try {
			String name = "Getraenkeladen_" + DateHandler.formatNormalDate(new Date());
			File source = new File(Configuration.DATABASENAME);
			File dest = new File(QueryFactory.getProperty(Property.PATHUSBSTICK)+name);
			
			CopyOption o = StandardCopyOption.REPLACE_EXISTING;
			Path res = Files.copy(source.toPath(), dest.toPath(), o);
			
			debug.debug("File saved in path: " + res);
			
		} catch (IOException e) {
			log.error(e.getMessage());
			e.printStackTrace();
		}
	}
	
	/**
	 * Reads String from file.
	 * @param path to the given File
	 * @return String containing the content of the file
	 */
	public static String readFromFile(String path){
		StringBuilder sb = new StringBuilder();
		try (BufferedReader br = new BufferedReader(new FileReader(path))) {
			String line = br.readLine();

			while (line != null) {
				sb.append(line);
				sb.append(System.lineSeparator());
				line = br.readLine();
			}
		} catch (IOException e) {
			log.error(e.getMessage());
			e.printStackTrace();
		}
		return sb.toString();
	}	
	
	/**
	 * Reads the SQL Statements from a file.
	 * <p>
	 * Is invoked if the DDL commands for creating the tables or the statements for initial values should be fired.
	 * 
	 * @param path Path of the file that should be read
	 * @return List of Strings containing each sql statement
	 */
	public static List<String> readFromIni(String path) {
		List<String> sqlStatementList = new ArrayList<>();

		try (BufferedReader br = new BufferedReader(new FileReader(path))) {
			StringBuilder sb = new StringBuilder();
			String line = br.readLine();

			while (line != null) {
				sb.append(line);
				sb.append(System.lineSeparator());
				if (line.contains(";")) {
					String statement = sb.toString();
					sqlStatementList.add(statement);
					debug.info("DDL command from .ini file read: " + sb.toString());
					sb.delete(0, sb.length() - 1);
				}
				line = br.readLine();
			}
		} catch (IOException e) {
			log.error(e.getMessage());
			e.printStackTrace();
		}
		return sqlStatementList;
	}
	
	/**
	 * Creates a .tex File.
	 * @param path of the file that should be created
	 * @param content that will be written to the file
	 * @return The created File | null if an error occurred
	 */
	public static File createTexFile(String path, String content){
		try {
			File f = new File(path);
			f.createNewFile();
			BufferedWriter bw = new BufferedWriter(new FileWriter(path));
			bw.write(content);
			bw.flush();
			bw.close();
			return f;
			
		} catch (IOException e) {
			log.error(e.getMessage());
			e.printStackTrace();
		}
		return null;		
	}

	/**
	 * Opens the given file with the program 'evince'.
	 * @param file to be opened
	 */
	public static void openPdf(File file) {
		try {
			Runtime.getRuntime().exec("evince " + file.getAbsolutePath());
		} catch (IOException e) {
			log.error(e.getMessage());
			e.printStackTrace();
		}
	}
}
